<template>
  <div>
    <t-card class="list-card-container" :bordered="false">
      <t-row justify="space-between">
        <t-input v-model="searchValue" class="search-input" placeholder="请输入关键词信息" clearable>
          <template #suffix-icon>
            <search-icon size="20px" />
          </template>
        </t-input>
        <div class="left-operation-container">
          <t-button @click="formVisible = true"> 新建 </t-button>
          <t-button variant="base" theme="default" :disabled="!selectedRowKeys.length" @click="exportCrawlers">
            导出
          </t-button>
        </div>
      </t-row>

      <div class="table-container">
        <t-table
          :columns="columns"
          :data="data"
          :rowKey="rowKey"
          :selected-row-keys="selectedRowKeys"
          :loading="dataLoading"
          :pagination="pagination"
          @page-change="rehandlePageChange"
          @change="rehandleChange"
          @select-change="rehandleSelectChange"
          :headerAffixedTop="true"
          :headerAffixProps="{ container: getContainer }"
        >
          <template #status="{ row }">
            <t-tag v-if="row.status === CRAWLER_STATUS.FAIL" theme="danger" variant="light">失败</t-tag>
            <t-tag v-if="row.status === CRAWLER_STATUS.RUNNING" theme="primary" variant="light">进行中</t-tag>
            <t-tag v-if="row.status === CRAWLER_STATUS.FINISH" theme="success" variant="light">已完成</t-tag>
          </template>
          <template #op="slotProps">
            <t-button
              size="small"
              shape="round"
              :theme="getButtonTheme(slotProps.row)"
              :disabled="isButtonDisabled(slotProps.row)"
              @click="startCrawler(slotProps.row)"
              :class="getButtonClass(slotProps.row)"
            >
              {{ getButtonText(slotProps.row) }}
            </t-button>
            <t-button
              size="small"
              shape="round"
              theme="default"
              :disabled="isOperationDisabled(slotProps.row)"
              @click="handleClickDetail(slotProps.row.task_id)"
            >
              详情
            </t-button>
            <t-button
              size="small"
              shape="round"
              theme="danger"
              :disabled="isOperationDisabled(slotProps.row)"
              @click="handleClickDelete(slotProps.row)"
            >
              删除
            </t-button>
          </template>
        </t-table>
      </div>
    </t-card>
    <!-- 删除操作弹窗 -->
    <t-dialog
      header="确认删除当前所选爬虫？"
      :body="confirmBody"
      :visible.sync="confirmVisible"
      @confirm="onConfirmDelete"
      :onCancel="onCancel"
    >
    </t-dialog>
    <!-- 新建爬虫弹窗 -->
    <t-dialog header="新建爬虫" :visible.sync="formVisible" :width="680" :footer="false">
      <div slot="body">
        <!-- 表单内容 -->
        <t-form :data="formData" ref="form" :rules="rules" @submit="onSubmit" :labelWidth="100">
          <t-form-item label="爬虫平台" name="platform_name">
            <t-select v-model="formData.platform_name" clearable :style="{ width: '480px' }" @change="onPlatformChange">
              <t-option v-for="(item, index) in platformOptions" :value="item.value" :label="item.label" :key="index">
                {{ item.label }}
              </t-option>
            </t-select>
          </t-form-item>
          <t-form-item label="爬虫类型" name="crawler_type">
            <t-select
              v-model="formData.crawler_type"
              clearable
              :style="{ width: '480px' }"
              @change="onCrawlerTypeChange"
            >
              <t-option v-for="(item, index) in typeOptions" :value="item.value" :label="item.label" :key="index">
                {{ item.label }}
              </t-option>
            </t-select>
          </t-form-item>
          <t-form-item v-if="showKeywordInput" label="关键词信息" name="keyword">
            <t-input :style="{ width: '480px' }" v-model="formData.keyword" placeholder="请输入关键词信息"></t-input>
          </t-form-item>
          <t-form-item v-if="showIdListInput" :label="idListLabel" name="id_list">
            <t-input :style="{ width: '480px' }" v-model="formData.id_list" :placeholder="idListPlaceholder"></t-input>
          </t-form-item>
          <t-form-item v-if="showCreatorListInput" :label="creatorListLabel" name="creator_list">
            <t-input
              :style="{ width: '480px' }"
              v-model="formData.creator_list"
              :placeholder="creatorListPlaceholder"
            ></t-input>
          </t-form-item>
          <t-form-item label="爬取评论" name="is_crawler_comment">
            <t-switch v-model="formData.is_crawler_comment" />
          </t-form-item>
          <t-form-item label="爬取子评论" name="is_crawler_sub_comment">
            <t-switch v-model="formData.is_crawler_sub_comment" />
          </t-form-item>
          <t-form-item label="开启IP代理" name="is_proxy_enabled">
            <t-switch v-model="formData.is_proxy_enabled" />
          </t-form-item>
          <t-form-item label="备注" name="remark">
            <t-textarea
              :style="{ width: '480px' }"
              v-model="formData.remark"
              placeholder="请输入描述信息"
              name="description"
            >
            </t-textarea>
          </t-form-item>
          <t-form-item style="float: right">
            <t-button variant="outline" @click="onClickCloseBtn">取消</t-button>
            <t-button theme="primary" type="submit">确定</t-button>
          </t-form-item>
        </t-form>
      </div>
    </t-dialog>
  </div>
</template>

<script lang="ts">
import Vue from 'vue';
import { SearchIcon } from 'tdesign-icons-vue';
import { CRAWLER_STATUS } from '../../constants/index';
import { mapState, mapGetters } from 'vuex';

const INITIAL_DATA = {
  platform_name: '',
  crawler_type: '',
  keyword: '',
  id_list: '',
  creator_list: '',
  is_crawler_comment: false,
  is_crawler_sub_comment: false,
  is_proxy_enabled: false,
  remark: '',
};

export default Vue.extend({
  name: 'DataCrawlerIndex',
  components: {
    SearchIcon,
  },
  data() {
    return {
      CRAWLER_STATUS,
      dataLoading: false,
      data: [],
      selectedRowKeys: [],
      searchValue: '',
      columns: [
        { colKey: 'row-select', type: 'multiple', width: 64, fixed: 'left' },
        {
          title: '平台名称',
          align: 'left',
          width: 150,
          ellipsis: true,
          colKey: 'platform_name',
          fixed: 'left',
        },
        { title: '爬虫类型', colKey: 'crawler_type', width: 150 },
        {
          title: '关键词信息',
          width: 200,
          ellipsis: true,
          colKey: 'keyword',
        },
        {
          title: '创建时间',
          width: 200,
          ellipsis: true,
          colKey: 'create_time',
        },
        {
          align: 'left',
          fixed: 'right',
          width: 150,
          colKey: 'remark',
          title: '备注',
        },
        {
          align: 'left',
          fixed: 'right',
          width: 100,
          colKey: 'status',
          title: '状态',
        },
        {
          align: 'center',
          fixed: 'right',
          width: 200,
          colKey: 'op',
          title: '操作',
        },
      ],
      platformOptions: [
        { label: '小红书', value: 'xhs' },
        { label: '抖音', value: 'dy' },
        { label: '哔哩哔哩', value: 'bili' },
        { label: '微博', value: 'wb' },
        { label: '快手', value: 'ks' },
        { label: '百度贴吧', value: 'tieba' },
        { label: '知乎', value: 'zhihu' },
      ],
      typeOptions: [
        { label: '关键词搜索', value: 'search' },
        { label: '帖子详情', value: 'detail' },
        { label: '创作者主页数据', value: 'creator' },
      ],
      formData: { ...INITIAL_DATA },
      rules: {
        platform_name: [{ required: true, message: '请选择平台名称', type: 'error' }],
        crawler_type: [{ required: true, message: '请选择爬虫类型', type: 'error' }],
        keyword: [
          {
            validator: (val: string) => {
              if ((this as any).showKeywordInput && !val) {
                return false;
              }
              return true;
            },
            message: '请输入关键词信息',
            type: 'error',
          },
        ],
        id_list: [
          {
            validator: (val: string) => {
              if (!(this as any).showIdListInput) return true;
              if (!val) return false;
              const idList = val.split(',').map((id) => id.trim());
              return idList.every((id) => id.length > 0);
            },
            message: '请输入有效的ID列表，多个ID以逗号分隔',
            type: 'error',
          },
        ],
        creator_list: [
          {
            validator: (val: string) => {
              if (!(this as any).showCreatorListInput) return true;
              if (!val) return false;
              const creatorList = val.split(',').map((creator) => creator.trim());
              return creatorList.every((creator) => creator.length > 0);
            },
            message: '请输入有效的创作者列表，多个创作者以逗号分隔',
            type: 'error',
          },
        ],
      },
      formVisible: false,
      rowKey: 'task_id',
      tableLayout: 'auto',
      verticalAlign: 'top',
      hover: true,
      rowClassName: (rowKey: string) => `${rowKey}-class`,
      pagination: {
        defaultPageSize: 20,
        defaultCurrent: 1,
      },
      confirmVisible: false,
      deleteIdx: null,
      selectedTasks: null,
      runningCrawlers: {} as Record<string, boolean>,
      showKeywordInput: false,
      showIdListInput: false,
      showCreatorListInput: false,
      idListLabel: '',
      idListPlaceholder: '',
      creatorListLabel: '',
      creatorListPlaceholder: '',
    };
  },
  computed: {
    confirmBody() {
      if (this.selectedTask) {
        const { platform_name } = this.selectedTask.platform_name;
        return `删除后，平台【${platform_name}】的该项配置信息及其关联数据将被删除！`;
      }
      return '';
    },
    ...mapState('notification', ['msgData']),
    ...mapGetters('notification', ['unreadMsg']),
    offsetTop() {
      return this.$store.state.setting.isUseTabsRouter ? 48 : 0;
    },
  },
  mounted() {
    this.fetchData();
  },

  methods: {
    getButtonText(row) {
      switch (row.status) {
      case CRAWLER_STATUS.RUNNING:
        return '运行中';
      case CRAWLER_STATUS.FINISH:
        return '运行成功';
      case CRAWLER_STATUS.FAIL:
        return '运行失败';
      default:
        return '运行';
      }
    },
    getButtonClass(row) {
      switch (row.status) {
      case CRAWLER_STATUS.RUNNING:
        return 'running-button';
      case CRAWLER_STATUS.FINISH:
        return 'success-button';
      case CRAWLER_STATUS.FAIL:
        return 'fail-button';
      default:
        return '';
      }
    },
    getButtonTheme(row) {
      switch (row.status) {
      case CRAWLER_STATUS.FINISH:
        return 'success';
      case CRAWLER_STATUS.FAIL:
        return 'danger';
      default:
        return 'default';
      }
    },
    isButtonDisabled(row) {
      return (
        row.status === CRAWLER_STATUS.RUNNING ||
        row.status === CRAWLER_STATUS.FINISH ||
        row.status === CRAWLER_STATUS.FAIL
      );
    },
    getContainer() {
      return document.querySelector('.tdesign-starter-layout');
    },
    rehandlePageChange(curr, pageInfo) {
      console.log('分页变化', curr, pageInfo);
      this.pagination.defaultCurrent = curr;
      this.fetchData();
    },
    rehandleSelectChange(selectedRowKeys: string[]) {
      this.selectedRowKeys = selectedRowKeys;
    },
    rehandleChange(changeParams, triggerAndData) {
      console.log('统一Change', changeParams, triggerAndData);
      // 例如处理排序和过滤
      this.fetchData();
    },
    handleClickDetail(taskId: string): void {
      this.$router.push({
        path: '/data-crawler/detail',
        query: { taskId },
      });
    },
    handleClickDelete(row: any) {
      this.selectedTask = row;
      this.confirmVisible = true;
    },
    async onConfirmDelete() {
      if (this.selectedTask) {
        try {
          const response = await this.$request.delete(
            `/system/crawler-configs/${this.selectedTask.task_id}/delete_with_data/`,
          );
          if (response.status === 204 || response.status === 200) {
            // 使用 task_id 查找并删除对应行
            const index = this.data.findIndex((item) => item.task_id === this.selectedTask.task_id);
            if (index > -1) {
              this.data.splice(index, 1);
            }
            this.pagination.total = this.data.length;
            this.$message.success(response.data.message);
            // 清除选中项
            this.selectedRowKeys = this.selectedRowKeys.filter((key) => key !== this.selectedTask.task_id);
          } else {
            this.$message.warning(response.data.message);
          }
        } catch (error) {
          console.error('删除失败:', error);
          this.$message.error('删除异常');
        } finally {
          this.confirmVisible = false;
          this.selectedTask = null; // 重置选中的任务
        }
      }
    },
    onCancel() {
      this.resetIdx();
    },
    resetIdx() {
      this.deleteIdx = -1;
    },

    // 检查爬虫是否在运行
    isRunning(row: any): boolean {
      return this.runningCrawlers[row.task_id] || false;
    },

    // 启动爬虫
    async startCrawler(row: any) {
      try {
        const response = await this.$request.post(`/system/crawler-configs/${row.task_id}/start-crawler/`);
        if (response.status === 202) {
          this.$message.success('爬虫启动成功');
          // 更新按钮状态
          this.$set(this.runningCrawlers, row.task_id, true);
          // 修改行状态为进行中
          this.$set(row, 'status', CRAWLER_STATUS.RUNNING);
          // 开始轮询状态
          this.pollCrawlerStatus(row.task_id, row.platform_name);
        } else {
          this.$message.error(`启动失败：${response.data.message}`);
          // 发送失败通知
          this.addNotification({
            id: this.generateUniqueId(),
            content: `爬虫任务【${row.platform_name}】启动失败：${response.statusText}`,
            type: '爬虫通知',
            status: true,
            collected: false,
            date: this.getCurrentDate(),
            quality: 'low',
          });
        }
      } catch (error) {
        console.error('启动爬虫异常:', error);
        this.$message.error('启动爬虫异常');
        // 发送异常通知
        this.addNotification({
          id: this.generateUniqueId(),
          content: `爬虫任务【${row.platform_name}】启动异常。`,
          type: '爬虫通知',
          status: true,
          collected: false,
          date: this.getCurrentDate(),
          quality: 'high',
        });
      }
    },

    // 轮询爬虫状态
    pollCrawlerStatus(task_id: string, platform_name: string) {
      const interval = setInterval(async () => {
        try {
          const response = await this.$request.get(`/system/crawler-configs/${task_id}/status/`);
          if (response.status === 200) {
            const { crawler_status, crawler_status_logs } = response.data;
            const row = this.data.find((item: any) => item.task_id === task_id);
            if (row) {
              this.$set(row, 'status', crawler_status);
              if (crawler_status === 'Succeed' || crawler_status === 'Failed') {
                clearInterval(interval);
                // 更新按钮状态
                this.$delete(this.runningCrawlers, task_id);
                if (crawler_status === 'Succeed') {
                  this.$message.success('爬虫已完成');
                  // 发送成功通知
                  this.addNotification({
                    id: this.generateUniqueId(),
                    content: `爬虫任务【${platform_name}】已完成。`,
                    type: '爬虫通知',
                    status: true,
                    collected: false,
                    date: this.getCurrentDate(),
                    quality: 'high',
                  });
                } else if (crawler_status === 'Failed') {
                  this.$message.error('爬虫运行失败');
                  // 发送失败通知
                  this.addNotification({
                    id: this.generateUniqueId(),
                    content: `爬虫任务【${platform_name}】运行失败: ${crawler_status_logs}`,
                    type: '爬虫通知',
                    status: true,
                    collected: false,
                    date: this.getCurrentDate(),
                    quality: 'low',
                  });
                }
              }
            }
          } else {
            this.$message.error(`状态查询失败：${response.statusText}`);
            clearInterval(interval);
            this.$delete(this.runningCrawlers, task_id);
            // 发送查询失败通知
            this.addNotification({
              id: this.generateUniqueId(),
              content: `爬虫任务【${platform_name}】状态查询失败：${response.statusText}`,
              type: '爬虫通知',
              status: true,
              collected: false,
              date: this.getCurrentDate(),
              quality: 'low',
            });
          }
        } catch (error) {
          console.error('查询爬虫状态异常:', error);
          this.$message.error('查询爬虫状态异常');
          clearInterval(interval);
          this.$delete(this.runningCrawlers, task_id);
          // 发送查询异常通知
          this.addNotification({
            id: this.generateUniqueId(),
            content: `爬虫任务【${platform_name}】状态查询异常。`,
            type: '爬虫通知',
            status: true,
            collected: false,
            date: this.getCurrentDate(),
            quality: 'high',
          });
        }
      }, 6000); // 每6秒轮询一次
    },

    // 添加通知到 Vuex
    addNotification(newMsg: any) {
      this.$store.commit('notification/addMsgData', newMsg);
    },

    // 生成唯一ID
    generateUniqueId(): string {
      return `${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    },

    // 获取当前日期时间
    getCurrentDate(): string {
      const now = new Date();
      const year = now.getFullYear();
      const month = String(now.getMonth() + 1).padStart(2, '0');
      const day = String(now.getDate()).padStart(2, '0');
      const hours = String(now.getHours()).padStart(2, '0');
      const minutes = String(now.getMinutes()).padStart(2, '0');
      return `${year}-${month}-${day} ${hours}:${minutes}`;
    },

    // 获取数据方法
    async fetchData() {
      this.dataLoading = true;
      try {
        const response = await this.$request.get('/system/crawler-configs/');
        if (response.status === 200) {
          this.data = response.data.map((item) => {
            const latestStatus = item.crawler_status || 'Unknown'; // 获取最新的状态
            return {
              ...item,
              status: latestStatus, // 将最新的状态赋值给 status
            };
          });
          this.pagination.total = this.data.length;
          console.log('this.pagination', this.pagination);
        } else {
          this.$message.warning('获取数据失败');
        }
      } catch (error) {
        console.error('获取数据失败:', error);
        this.$message.error('获取数据失败');
      } finally {
        this.dataLoading = false;
      }
    },

    // 提交方法：创建新爬虫
    async onSubmit({ result, firstError }): Promise<void> {
      if (!firstError) {
        try {
          const requestData = {
            ...this.formData,
            id_list: this.formData.id_list ? this.formData.id_list.split(',').map((id) => id.trim()) : [],
            creator_list: this.formData.creator_list
              ? this.formData.creator_list.split(',').map((creator) => creator.trim())
              : [],
          };
          const response = await this.$request.post('/system/crawler-configs/', requestData);
          if (response.status === 201 || response.status === 200) {
            this.$message.success('提交成功');
            this.formVisible = false;
            this.data.unshift(response.data);
            this.pagination.total = this.data.length;
            this.$refs.form.reset();
          } else {
            this.$message.warning(response.data.message);
          }
        } catch (error) {
          console.error('提交失败:', error);
          this.$message.error('提交异常');
        }
      } else {
        console.log('Errors: ', result);
        this.$message.warning(firstError);
      }
    },

    onClickCloseBtn() {
      this.formData = { ...INITIAL_DATA };
      this.formVisible = false;
    },
    exportCrawlers() {
      console.log('导出爬虫');
    },

    isOperationDisabled(row) {
      return row.status === CRAWLER_STATUS.RUNNING;
    },
    onPlatformChange() {
      this.formData.crawler_type = '';
      this.updateFormFields();
    },
    onCrawlerTypeChange() {
      this.updateFormFields();
    },
    updateFormFields() {
      const platform = this.formData.platform_name;
      const crawlerType = this.formData.crawler_type;

      this.showKeywordInput = crawlerType === 'search';
      this.showIdListInput = crawlerType === 'detail';
      this.showCreatorListInput = crawlerType === 'creator';

      switch (platform) {
      case 'xhs':
        this.idListLabel = '笔记ID列表';
        this.idListPlaceholder = '请输入小红书笔记ID，多个ID以逗号分隔';
        this.creatorListLabel = '创作者ID列表';
        this.creatorListPlaceholder = '请输入小红书创作者ID，多个ID以逗号分隔';
        break;
      case 'wb':
        this.idListLabel = '帖子ID列表';
        this.idListPlaceholder = '请输入微博帖子ID，多个ID以逗号分隔';
        this.creatorListLabel = '创作者ID列表';
        this.creatorListPlaceholder = '请输入微博创作者ID，多个ID以逗号分隔';
        break;
      case 'tieba':
        this.idListLabel = '帖子ID列表';
        this.idListPlaceholder = '请输入贴吧帖子ID，多个ID以逗号分隔';
        this.creatorListLabel = '创作者URL列表';
        this.creatorListPlaceholder = '请输入贴吧创作者主页URL，多个URL以逗号分隔';
        break;
      case 'bili':
        this.idListLabel = '视频ID列表';
        this.idListPlaceholder = '请输入B站视频ID，多个ID以逗号分隔';
        this.creatorListLabel = '创作者ID列表';
        this.creatorListPlaceholder = '请输入B站创作者ID，多个ID以逗号分隔';
        break;
      case 'dy':
        this.idListLabel = '视频ID列表';
        this.idListPlaceholder = '请输入抖音视频ID，多个ID以逗号分隔';
        this.creatorListLabel = '创作者ID列表';
        this.creatorListPlaceholder = '请输入抖音创作者ID，多个ID以逗号分隔';
        break;
      case 'ks':
        this.idListLabel = '视频ID列表';
        this.idListPlaceholder = '请输入快手视频ID，多个ID以逗号分隔';
        this.creatorListLabel = '创作者ID列表';
        this.creatorListPlaceholder = '请输入快手创作者ID，多个ID以逗号分隔';
        break;
      case 'zhihu':
        this.creatorListLabel = '创作者URL列表';
        this.idListLabel = '帖子ID列表';
        this.idListPlaceholder = '请输入知乎帖子ID，多个ID以逗号分隔';
        this.creatorListPlaceholder = '请输入知乎创作者主页URL，多个URL以逗号分隔';
        break;
      default:
        break;
      }
    },
  },
});
</script>

<style lang="less" scoped>
@import './index.ts';

.list-card-container {
  padding: 20px;
}

.payment-col {
  display: flex;

  .trend-container {
    display: flex;
    align-items: center;
    margin-left: 8px;
  }
}

.left-operation-container {
  padding: 0 0 6px 0;
  margin-bottom: 16px;

  .selected-count {
    display: inline-block;
    margin-left: var(--td-comp-margin-s);
    color: var(--td-text-color-secondary);
  }
}

.search-input {
  width: 260px;
}

.t-button + .t-button {
  margin-left: var(--td-comp-margin-s);
}

.table-container {
  margin-top: 20px;
}

.running-button {
  color: blue;
}

.success-button {
  color: green;
}

.fail-button {
  color: red;
}
/* 其他样式根据需要添加 */
</style>
